package 反射;

import java.lang.reflect.Method;

//java.lang.reflect.Method.invoke() 方法来反射调用一个方法，当然一般只用于正常情况下无法直接访问的方法（比如：private 的方法，或者无法或者该类的对象）。
//
//定义
//public native Object invoke(Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
//参数：
//第一个参数是方法属于的对象（如果是静态方法，则可以直接传 null）
//第二个可变参数是该方法的参数
//返回值：Object
//异常：
//如果调用的方法有抛出异常，异常会被 java.lang.reflect.InvocationTargetException 包一层

//在框架中经常会会用到method.invoke()方法，用来执行某个的对象的目标方法。以前写代码用到反射时，总是获取先获取Method，然后传入对应的Class实例对象执行方法。
//然而前段时间研究invoke方法时，发现invoke方法居然包含多态的特性，这是以前没有考虑过的一个问题。那么Method.invoke()方法的执行过程是怎么实现的？
//它的多态又是如何实现的呢？
//
//首先给出invoke方法多态特性的演示代码：

//public class MethodInvoke {
public class 使用invoke {
 
	public static void main(String[] args) throws Exception {
		//getDeclaredMethod(String name, Class[] params)
		Method animalMethod = Animal.class.getDeclaredMethod("print");
		Method catMethod = Cat.class.getDeclaredMethod("print");
		
		Animal animal = new Animal();
		Cat cat = new Cat();
		animalMethod.invoke(cat);
		animalMethod.invoke(animal);
		
		catMethod.invoke(cat);
//		catMethod.invoke(animal);
	}
	
}
 
class Animal {
	public void print() {
		System.out.println("Animal.print()");
	}
}
class Cat extends Animal {
	@Override
	public void print() {
		System.out.println("Cat.print()");
	}
}
//代码中，Cat类覆盖了父类Animal的print()方法， 然后通过反射分别获取print()的Method对象。最后分别用Cat和Animal的实例对象去执行print()方法。
//其中animalMethod.invoke(animal)和catMethod.invoke(cat)，示例对象的真实类型和Method的声明Classs是相同的，
//按照预期打印结果；animalMethod.invoke(cat)中，由于Cat是Animal的子类，按照多态的特性，子类调用父类的的方法，方法执行时会动态链接到子类的实现
//方法上。因此，这里会调用Cat.print()方法；而catMethod.invoke(animal)中，传入的参数类型Animal是父类，却期望调用子类Cat的方法，
//因此这一次会抛出异常。代码打印结果为：
//
//Cat.print()
//Animal.print()
//Cat.print()
//Exception in thread "main" java.lang.IllegalArgumentException: object is not an instance of declaring class
//	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
//	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
//	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
//	at java.lang.reflect.Method.invoke(Unknown Source)
//	at com.wy.invoke.MethodInvoke.main(MethodInvoke.java:17)
//接下来，我们来看看invoke()方法的实现过程。
//
//public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
//    if (!override) {
//        if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
//            Class<?> caller = Reflection.getCallerClass(1);
//
//            checkAccess(caller, clazz, obj, modifiers);
//        }
//    }
//    MethodAccessor ma = methodAccessor;             // read volatile
//    if (ma == null) {
//        ma = acquireMethodAccessor();
//    }
//    return ma.invoke(obj, args);
//}
//invoke()方法中主要分为两部分：访问控制检查和调用MethodAccessor.invoke()实现方法执行。
//
//首先看一下访问控制检查这一块的逻辑。第一眼看到这里的逻辑的时候，很容易搞不清楚是干嘛的。
//通俗来讲就是通过方法的修饰符(public/protected/private/package)，来判断方法的调用者是否可以访问该方法。这是java的基础内容，
//不过用代码写出来，一下子不容易想到。访问控制检查分为3步：
//
//检查override，如果override为true，跳过检查；否则继续；
//快速检查，判断该方法的修饰符modifiers是否为public，如果是跳过检查；否则继续；
//详细检查，通过方法的(protected/private/package)修饰符或方法的声明类（例如子类可以访问父类的protected方法）与调用者caller之间的关系，判断caller是否有权限访问该方法。
//override属性是Method的父类AccessibleObject中声明的变量，使得程序可以控制是否跳过访问权限的检查。另外，Method的实例对象中，override属性的初始值设置为false。
//
//    public void setAccessible(boolean flag) throws SecurityException {
//        SecurityManager sm = System.getSecurityManager();
//        if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
//        setAccessible0(this, flag);
//    }
// 
//    private static void setAccessible0(AccessibleObject obj, boolean flag)
//        throws SecurityException
//    {
//        if (obj instanceof Constructor && flag == true) {
//            Constructor<?> c = (Constructor<?>)obj;
//            if (c.getDeclaringClass() == Class.class) {
//                throw new SecurityException("Can not make a java.lang.Class" +
//                                            " constructor accessible");
//            }
//        }
//        obj.override = flag;
//    }
//多说一句，Field同样继承了AccessibleObject，且Field的override也是初始化为false的，也就是说并没有按照变量的修饰符去初始化不同的值。但是我们在调用Field.set(Object obj, Object value)时，如果该Field是private修饰的，会因没有访问权限而抛出异常，因此必须调用setAccessible(true)。此处非常容易理解为因为变量是public的，所以override就被初始化为true。
//
//invoke()方法中，访问控制检查之后，就是通过MethodAccessor.invoke()调用方法。再来看一下代码：
//
//        MethodAccessor ma = methodAccessor;             // read volatile
//        if (ma == null) {
//            ma = acquireMethodAccessor();
//        }
//        return ma.invoke(obj, args);
//这里的逻辑很简单，首先将变量methodAccessor赋值给ma，在方法栈中保存一个可以直接引用的本地变量，如果methodAccessor不存在，调用acquireMethodAccessor()方法创建一个。
//
//    private volatile MethodAccessor methodAccessor;
//    private Method root;
//    
//    private MethodAccessor acquireMethodAccessor() {
//        // First check to see if one has been created yet, and take it
//        // if so
//        MethodAccessor tmp = null;
//        if (root != null) tmp = root.getMethodAccessor();
//        if (tmp != null) {
//            methodAccessor = tmp;
//        } else {
//            // Otherwise fabricate one and propagate it up to the root
//            tmp = reflectionFactory.newMethodAccessor(this);
//            setMethodAccessor(tmp);
//        }
// 
//        return tmp;
//    }
// 
//    void setMethodAccessor(MethodAccessor accessor) {
//        methodAccessor = accessor;
//        // Propagate up
//        if (root != null) {
//            root.setMethodAccessor(accessor);
//        }
//    }
// 
//    Method copy() {
//        Method res = new Method(clazz, name, parameterTypes, returnType,
//                                exceptionTypes, modifiers, slot, signature,
//                                annotations, parameterAnnotations, annotationDefault);
//        res.root = this;
//        res.methodAccessor = methodAccessor;
//        return res;
//    }
//综合acquireMethodAccessor(),setMethodAccessor()以及copy()这三个方法，可以看到一个Method实例对象维护了一个root引用。当调用Method.copy()进行方法拷贝时，root指向了被拷贝的对象。那么当一个Method被多次拷贝后，调用一次setMethodAccessor()方法，就会将root引用所指向的Method的methodAccessor变量同样赋值。例如：D -> C -> B -> A，其中X-> Y表示X = Y.copy()， 当C对象调用setMethodAccessor()时，B和A都会传播赋值methodAccessor， 而D的methodAccessor还是null。紧接着，当D需要获取methodAccessor而调用acquireMethodAccessor()时，D获取root的methodAccessor， 那么D将和ABC持有相同的methodAccessor。
//
//虽然Method中，通过维护root引用意图使相同的方法始终保持只有一个methodAccessor实例，但是上述方法仍然无法保证相同的方法只有一个methodAccessor实例。例如通过copy()使ABCD保持关系：D -> C -> B -> A， 当B对象调用setMethodAccessor()时，B和A都会赋值methodAccessor， 而C、D的methodAccessor还是null。这时D调用acquireMethodAccessor()时，D获取root也就是C的methodAccessor，发现为空，然后就新创建了一个。从而出现了相同的方法中出现了两个methodAccessor实例对象的现象。
//
//在Class.getMethod()、Class.getDeclaredMethod()以及Class.getDeclaredMethod(String name, Class<?>... parameterTypes)方法中最终都会调用copy()方法来保障Method使用的安全性。 在比较极端加巧合的情况下，可能会引起类膨胀的问题，这就是接下来要讲到的MethodAccessor的实现机制。
//
//
//
//在前面代码中，MethodAccessor的创建是通过反射工厂ReflectionFactory的newMethodAccessor(Method)方法来创建的。
//
//    public MethodAccessor newMethodAccessor(Method method) {
//        checkInitted();
// 
//        if (noInflation) {
//            return new MethodAccessorGenerator().
//                generateMethod(method.getDeclaringClass(),
//                               method.getName(),
//                               method.getParameterTypes(),
//                               method.getReturnType(),
//                               method.getExceptionTypes(),
//                               method.getModifiers());
//        } else {
//            NativeMethodAccessorImpl acc =
//                new NativeMethodAccessorImpl(method);
//            DelegatingMethodAccessorImpl res =
//                new DelegatingMethodAccessorImpl(acc);
//            acc.setParent(res);
//            return res;
//        }
//    }
//其中， checkInitted()方法检查从配置项中读取配置并设置noInflation、inflationThreshold的值：
//
//    private static void checkInitted() {
//        if (initted) return;
//        AccessController.doPrivileged(
//            new PrivilegedAction<Void>() {
//                public Void run() {
// 
//                    if (System.out == null) {
//                        // java.lang.System not yet fully initialized
//                        return null;
//                    }
// 
//                    String val = System.getProperty("sun.reflect.noInflation");
//                    if (val != null && val.equals("true")) {
//                        noInflation = true;
//                    }
// 
//                    val = System.getProperty("sun.reflect.inflationThreshold");
//                    if (val != null) {
//                        try {
//                            inflationThreshold = Integer.parseInt(val);
//                        } catch (NumberFormatException e) {
//                            throw (RuntimeException)
//                                new RuntimeException("Unable to parse property sun.reflect.inflationThreshold").
//                                    initCause(e);
//                        }
//                    }
// 
//                    initted = true;
//                    return null;
//                }
//            });
//    }
//可以通过启动参数-Dsun.reflect.noInflation=false -Dsun.reflect.inflationThreshold=15来设置：
//
//
//
//结合字面意思及下面代码理解，这两个配置sun.reflect.noInflation是控制是否立即进行类膨胀，sun.reflect.inflationThreshold是设置类膨胀阈值。
//
//创建MethodAccessor有两种选择，一种是当sun.reflect.noInflation配置项为true时，ReflectionFactory利用MethodAccessor的字节码生成类 MethodAccessorGenerator直接创建一个代理类，通过间接调用原方法完成invoke()任务，具体实现稍后给出。MethodAccessor的另一种实现方式是，创建DelegatingMethodAccessorImpl 委托类，并将执行invoke()方法的具体内容交由NativeMethodAccessorImpl实现，而NativeMethodAccessorImpl最终调用native方法完成invoke()任务。以下是NativeMethodAccessorImpl的invoke()方法实现。
//
//    public Object invoke(Object obj, Object[] args) 
//        throws IllegalArgumentException, InvocationTargetException
//    {
//        if (++numInvocations > ReflectionFactory.inflationThreshold()) {
//            MethodAccessorImpl acc = (MethodAccessorImpl)
//                new MethodAccessorGenerator().
//                    generateMethod(method.getDeclaringClass(),
//                                   method.getName(),
//                                   method.getParameterTypes(),
//                                   method.getReturnType(),
//                                   method.getExceptionTypes(),
//                                   method.getModifiers());
//            parent.setDelegate(acc);
//        }
// 
//        return invoke0(method, obj, args);
//    }
// 
//    private static native Object invoke0(Method m, Object obj, Object[] args);
//可以看到，当numInvocations数量大于配置项sun.reflect.inflationThreshold即类膨胀阈值时， 使用MethodAccessorGenerator创建一个代理类对象，并且将被委托的NativeMethodAccessorImpl的parent，也就是委托类DelegatingMethodAccessorImpl的委托类设置为这个生成的代理对象。这么说可能有点绕，下面用一幅图表示这个过程。
//
//
//
//总体来说，当调用invoke()时，按照默认配置，Method首先创建一个DelegatingMethodAccessorImpl对象，并设置一个被委托的NativeMethodAccessorImpl对象，那么method.invoke()就被转换成DelegatingMethodAccessorImpl.invoke()，然后又被委托给NativeMethodAccessorImp.invoke()实现。当NativeMethodAccessorImp.invoke()调用次数超过一定热度时（默认15次），被委托方又被转换成代理类来实现。
//
//之前提到过在极端情况下，同一个方法的Method对象存在多个不同拷贝拷贝时，可能存在多个MethodAccessor对象。那么当多次调用后，必然会生成两个重复功能的代理类。当然，一般情况下，生成两个代理类并没有较大的影响。
//
//其中代理类的具体字节码实现过程较为复杂，大体思想是生成一个如下所示的类：
//
//public class GeneratedMethodAccessor1 extends MethodAccessorImpl {
// 
//	public GeneratedMethodAccessor1 () {
//	    super();
//	}
//	
//	public Object invoke(Object obj, Object[] args)
//	        throws IllegalArgumentException, InvocationTargetException 
//	{
//		if (!(obj instanceof Cat)) {
//			throw new ClassCastException();
//		}
//		if (args != null && args.length != 0) {
//			throw new IllegalArgumentException();
//		}
//		
//		try {
//			Cat cat = (Cat) obj;
//			cat.print();
//			return null;
//		} catch (Throwable e) {
//			throw new InvocationTargetException(e, "invoke error");
//		}
//	}
//	
//}
//到目前为止，除了在代理的GeneratedMethodAccessor1 类中，方法的执行有多态的特性，而NativeMethodAccessorImp的invoke()实现是在jdk中的完成的。接下来我们将目光移到NativeMethodAccessorImp的native方法invoke0();
//
//openJDK下载地址
//
//首先，在\jdk\src\share\native\sun\reflect路径下找到NativeAccessors.c， 其中有Java_sun_reflect_NativeMethodAccessorImpl _invoke0()方法，根据JNI定义函数名的规则"包名_类名_方法名"，这就是我们要找的native方法实现入口。
//
//JNIEXPORT jobject JNICALL Java_sun_reflect_NativeMethodAccessorImpl_invoke0
//(JNIEnv *env, jclass unused, jobject m, jobject obj, jobjectArray args)
//{
//    return JVM_InvokeMethod(env, m, obj, args);
//}
//方法调用JVM_InvokeMethod(), 一般以JVM_开头的函数定义在jvm.cpp文件中，不熟悉的话可以通过头文件jvm.h看出来。继续追踪，发现jvm.cpp文件位于spot\src\share\vm\prims文件夹下。
//
//JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0))
//  JVMWrapper("JVM_InvokeMethod");
//  Handle method_handle;
//  if (thread->stack_available((address) &method_handle) >= JVMInvokeMethodSlack) {
//    method_handle = Handle(THREAD, JNIHandles::resolve(method));
//    Handle receiver(THREAD, JNIHandles::resolve(obj));
//    objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));
//    oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL);
//    jobject res = JNIHandles::make_local(env, result);
//    if (JvmtiExport::should_post_vm_object_alloc()) {
//      oop ret_type = java_lang_reflect_Method::return_type(method_handle());
//      assert(ret_type != NULL, "sanity check: ret_type oop must not be NULL!");
//      if (java_lang_Class::is_primitive(ret_type)) {
//        // Only for primitive type vm allocates memory for java object.
//        // See box() method.
//        JvmtiExport::post_vm_object_alloc(JavaThread::current(), result);
//      }
//    }
//    return res;
//  } else {
//    THROW_0(vmSymbols::java_lang_StackOverflowError());
//  }
//JVM_END
//其中oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL)是方法的执行过程，在\hotspot\src\share\vm\runtime路径下找到reflection.cpp文件。
//
//oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) {
//  oop mirror             = java_lang_reflect_Method::clazz(method_mirror);
//  int slot               = java_lang_reflect_Method::slot(method_mirror);
//  bool override          = java_lang_reflect_Method::override(method_mirror) != 0;
//  objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror)));
// 
//  oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror);
//  BasicType rtype;
//  if (java_lang_Class::is_primitive(return_type_mirror)) {
//    rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
//  } else {
//    rtype = T_OBJECT;
//  }
// 
//  instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
//  Method* m = klass->method_with_idnum(slot);
//  if (m == NULL) {
//    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
//  }
//  methodHandle method(THREAD, m);
// 
//  return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
//}
// 
//oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
//                       Handle receiver, bool override, objArrayHandle ptypes,
//                       BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) {
//  ResourceMark rm(THREAD);
// 
//  methodHandle method;      // actual method to invoke
//  KlassHandle target_klass; // target klass, receiver's klass for non-static
// 
//  // Ensure klass is initialized
//  klass->initialize(CHECK_NULL);
// 
//  bool is_static = reflected_method->is_static();
//  if (is_static) {
//    // ignore receiver argument
//    method = reflected_method;
//    target_klass = klass;
//  } else {
//    // check for null receiver
//    if (receiver.is_null()) {
//      THROW_0(vmSymbols::java_lang_NullPointerException());
//    }
//    // Check class of receiver against class declaring method
//    if (!receiver->is_a(klass())) {
//      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
//    }
//    // target klass is receiver's klass
//    target_klass = KlassHandle(THREAD, receiver->klass());
//    // no need to resolve if method is private or <init>
//    if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) {
//      method = reflected_method;
//    } else {
//      // resolve based on the receiver
//      if (reflected_method->method_holder()->is_interface()) {
//        // resolve interface call
//        if (ReflectionWrapResolutionErrors) {
//          // new default: 6531596
//          // Match resolution errors with those thrown due to reflection inlining
//          // Linktime resolution & IllegalAccessCheck already done by Class.getMethod()
//          method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD);
//          if (HAS_PENDING_EXCEPTION) {
//          // Method resolution threw an exception; wrap it in an InvocationTargetException
//            oop resolution_exception = PENDING_EXCEPTION;
//            CLEAR_PENDING_EXCEPTION;
//            JavaCallArguments args(Handle(THREAD, resolution_exception));
//            THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
//                vmSymbols::throwable_void_signature(),
//                &args);
//          }
//        } else {
//          method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL));
//        }
//      }  else {
//        // if the method can be overridden, we resolve using the vtable index.
//        assert(!reflected_method->has_itable_index(), "");
//        int index = reflected_method->vtable_index();
//        method = reflected_method;
//        if (index != Method::nonvirtual_vtable_index) {
//          // target_klass might be an arrayKlassOop but all vtables start at
//          // the same place. The cast is to avoid virtual call and assertion.
//          InstanceKlass* inst = (InstanceKlass*)target_klass();
//          method = methodHandle(THREAD, inst->method_at_vtable(index));
//        }
//        if (!method.is_null()) {
//          // Check for abstract methods as well
//          if (method->is_abstract()) {
//            // new default: 6531596
//            if (ReflectionWrapResolutionErrors) {
//              ResourceMark rm(THREAD);
//              Handle h_origexception = Exceptions::new_exception(THREAD,
//                     vmSymbols::java_lang_AbstractMethodError(),
//                     Method::name_and_sig_as_C_string(target_klass(),
//                     method->name(),
//                     method->signature()));
//              JavaCallArguments args(h_origexception);
//              THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
//                vmSymbols::throwable_void_signature(),
//                &args);
//            } else {
//              ResourceMark rm(THREAD);
//              THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(),
//                        Method::name_and_sig_as_C_string(target_klass(),
//                                                                method->name(),
//                                                                method->signature()));
//            }
//          }
//        }
//      }
//    }
//  }
// 
//  // I believe this is a ShouldNotGetHere case which requires
//  // an internal vtable bug. If you ever get this please let Karen know.
//  if (method.is_null()) {
//    ResourceMark rm(THREAD);
//    THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
//                Method::name_and_sig_as_C_string(klass(),
//                                                        reflected_method->name(),
//                                                        reflected_method->signature()));
//  }
// 
//  // In the JDK 1.4 reflection implementation, the security check is
//  // done at the Java level
//  if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) {
// 
//  // Access checking (unless overridden by Method)
//  if (!override) {
//    if (!(klass->is_public() && reflected_method->is_public())) {
//      bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL);
//      if (!access) {
//        return NULL; // exception
//      }
//    }
//  }
// 
//  } // !(Universe::is_gte_jdk14x_version() && UseNewReflection)
// 
//  assert(ptypes->is_objArray(), "just checking");
//  int args_len = args.is_null() ? 0 : args->length();
//  // Check number of arguments
//  if (ptypes->length() != args_len) {
//    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "wrong number of arguments");
//  }
// 
//  // Create object to contain parameters for the JavaCall
//  JavaCallArguments java_args(method->size_of_parameters());
// 
//  if (!is_static) {
//    java_args.push_oop(receiver);
//  }
// 
//  for (int i = 0; i < args_len; i++) {
//    oop type_mirror = ptypes->obj_at(i);
//    oop arg = args->obj_at(i);
//    if (java_lang_Class::is_primitive(type_mirror)) {
//      jvalue value;
//      BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL);
//      BasicType atype = unbox_for_primitive(arg, &value, CHECK_NULL);
//      if (ptype != atype) {
//        widen(&value, atype, ptype, CHECK_NULL);
//      }
//      switch (ptype) {
//        case T_BOOLEAN:     java_args.push_int(value.z);    break;
//        case T_CHAR:        java_args.push_int(value.c);    break;
//        case T_BYTE:        java_args.push_int(value.b);    break;
//        case T_SHORT:       java_args.push_int(value.s);    break;
//        case T_INT:         java_args.push_int(value.i);    break;
//        case T_LONG:        java_args.push_long(value.j);   break;
//        case T_FLOAT:       java_args.push_float(value.f);  break;
//        case T_DOUBLE:      java_args.push_double(value.d); break;
//        default:
//          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
//      }
//    } else {
//      if (arg != NULL) {
//        Klass* k = java_lang_Class::as_Klass(type_mirror);
//        if (!arg->is_a(k)) {
//          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
//        }
//      }
//      Handle arg_handle(THREAD, arg);         // Create handle for argument
//      java_args.push_oop(arg_handle); // Push handle
//    }
//  }
// 
//  assert(java_args.size_of_parameters() == method->size_of_parameters(), "just checking");
// 
//  // All oops (including receiver) is passed in as Handles. An potential oop is returned as an
//  // oop (i.e., NOT as an handle)
//  JavaValue result(rtype);
//  JavaCalls::call(&result, method, &java_args, THREAD);
// 
//  if (HAS_PENDING_EXCEPTION) {
//    // Method threw an exception; wrap it in an InvocationTargetException
//    oop target_exception = PENDING_EXCEPTION;
//    CLEAR_PENDING_EXCEPTION;
//    JavaCallArguments args(Handle(THREAD, target_exception));
//    THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
//                vmSymbols::throwable_void_signature(),
//                &args);
//  } else {
//    if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT)
//      narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL);
//    return box((jvalue*) result.get_value_addr(), rtype, CHECK_NULL);
//  }
//}
//Reflection::invoke_method()中调用Reflection::invoke()，然后在Reflection::invoke()方法中，当反射调用的方法是接口方法时，调用Reflection::resolve_interface_call()，该方法依赖LinkResolver::resolve_interface_call()来完成方法的动态链接过程，具体实现就不在这里展示。
//
//method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL));
//methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method,
//                                                KlassHandle recv_klass, Handle receiver, TRAPS) {
//  assert(!method.is_null() , "method should not be null");
// 
//  CallInfo info;
//  Symbol*  signature  = method->signature();
//  Symbol*  name       = method->name();
//  LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass,
//                                       name, signature,
//                                       KlassHandle(), false, true,
//                                       CHECK_(methodHandle()));
//  return info.selected_method();
//}
//如果反射调用的方法是可以被覆盖的方法，例如Animal.print()， Reflection::invoke()最终通过查询虚方法表vtable来确定最终的method。
//
//        // if the method can be overridden, we resolve using the vtable index.
//        assert(!reflected_method->has_itable_index(), "");
//        int index = reflected_method->vtable_index();
//        method = reflected_method;
//        if (index != Method::nonvirtual_vtable_index) {
//          // target_klass might be an arrayKlassOop but all vtables start at
//          // the same place. The cast is to avoid virtual call and assertion.
//          InstanceKlass* inst = (InstanceKlass*)target_klass();
//          method = methodHandle(THREAD, inst->method_at_vtable(index));
//        }
 

//总结
//1.method.invoke()方法支持多态特性，其native实现在方法真正执行之前通过动态连接或者虚方法表来实现。
//
//2.框架中使用method.invoke()执行方法调用时，初始获取method对象时，可以先调用一次setAccessable(true)，使得后面每次调用invoke()时，
//节省一次方法修饰符的判断，略微提升性能。业务允许的情况下，Field同样可以如此操作。
//
//3.委托模式可以解决一种方案的多种实现之间自由切换，而代理模式只能根据传入的被代理对象来实现功能。





